热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

每日一博|java通过网络唤醒实现远程开机

每日一博|java通过网络唤醒实现远程开机

1. 在BIOS设置支持网络唤醒

大多数集成网卡都能实现 网络唤醒 功能,不过需要事先进入BIOS中开启网络唤醒功能,不同主板的设置不一样,以VIA 主板为例,在BIOS中找到“OnBoard LAN”选项,将它设成“Enabled”。同时将“POWER MANAGEMENT SETUP( 电源管理 设置)”下的“Power On by LAN/Ring”选项设为“Enabled”,最后将“Wake On LAN(网络唤醒)”选项设置为“Enabled”,设置好后保存退出。

不同系统可能还需要额外的操作才能保证网络唤醒的可用性,以win10系统为例:

打开设备管理器,进入网络适配器中自己网卡的属性设置,把相关的服务都启用了。

每日一博 | java 通过网络唤醒实现远程开机

2. 网络唤醒的必备条件

  • 网络唤醒需要终端的主板和网卡支持,需要先在BIOS设置支持网络唤醒
  • 网络唤醒要接通电源保证网卡能通电 要接网线 不能是wifi
  • 如果强制关机 可能不能通过网络唤醒来开机
  • 跨交换机或者跨路由的话就有可能不支持唤醒
  • 跨多层交换机的话即使ping通也未必能唤醒
  • 在同一网段下进行网络唤醒最为省事

3. 网络唤醒原理

这里提到一个魔术包 Magic Packet 的概念,魔术包指AMD公司开发的唤醒数据包,其实是一种特定的数据格式。将唤醒魔术包发送的被唤醒机器的网卡上,具有远程唤醒的网卡都支持这个标准,用16进制表示。

假设你的网卡物理地址为00:15:17:53:d4:f9, 这段Magic Packet内容如下:

FFFFFFFFFFFF00151753d4f900151753d4f900151753d4f900151753d4f9

00151753d4f900151753d4f900151753d4f900151753d4f900151753d4f9

00151753d4f900151753d4f900151753d4f900151753d4f900151753d4f9

00151753d4f900151753d4f9

这段数据转化为二进制的数据,通过socket技术发送数据包以及目的mac和目的广播地址,就会唤醒目的网卡,从而唤醒主机。

数据包流向图:

每日一博 | java 通过网络唤醒实现远程开机

当数据包被广播到192.168.1网段之后,根据数据携带的mac信息匹配到具体的主机。

4. 广播地址

这里主要讲解广播地址的概念和计算。

所谓 广播地址 指同时向网上所有的主机发送报文。

对一个既定的ip来说,其网络地址就是主机位全换成0, 广播地址 就是主机位是全换成1

例子:先把子网掩码化成二进制,再对应的把子网掩码后面是0的部分对着Ip地址换成0和1就是网络地址和 主机地址 ,比如

192.168.1.3 (地址)/255.255.255.252(掩码) ,换算一下成二进制

11111111.11111111.11111111.111111 00 /掩码

11000000.10101000.00000001.000000 11 /地址

掩码后两位是0,那么把地址的后两位换成0就是网络地址,换成1就是 广播地址

那么就是:11000000.10101000.00000001.000000 00

11000000.10101000.00000001.000000 11

把上面的 二进制转换 成10进制

得到192.168.1.0是网络地址,192.168.1.3是 广播地址 。

5. java代码-网络唤醒

先计算被唤醒主机的广播地址

//根据子网掩码和ip得到主机的广播地址
    public static String getBroadcastAddress(String ip, String subnetMask){
        String ipBinary = toBinary(ip);
        String subnetBinary = toBinary(subnetMask);
        String broadcastBinary = getBroadcastBinary(ipBinary, subnetBinary);
        String wholeBroadcastBinary=spiltBinary(broadcastBinary);
        return binaryToDecimal(wholeBroadcastBinary);
    }

    //二进制的ip字符串转十进制
    private static String binaryToDecimal(String wholeBroadcastBinary){
        String[] strings = wholeBroadcastBinary.split("\\.");
        StringBuilder sb = new StringBuilder(40);
        for (int j = 0; j  
 

执行网络唤醒

/**
     * 唤醒主机
     * @param ip         主机ip
     * @param mac     主机mac
     * @param subnetMask      主机子网掩码
     */
    public static void wakeUpDevice(String ip,String mac,String subnetMask){
        ip=ip.trim();
        mac=mac.trim();
        subnetMask=subnetMask.trim();
        String broadcastAddress=getBroadcastAddress(ip,subnetMask);
        mac = mac.replace("-", "");
        wakeBy(broadcastAddress,mac,389);
    }

    /**
     *   网络唤醒
     * @param ip            主机ip
     * @param mac        主机mac
     * @param port        端口
     */
    private static void wakeBy(String ip, String mac, int port) {
        //构建magic魔术包
        String MagicPacage = "FFFFFFFFFFFF";
        for (int i = 0; i <16; i++) {
            MagicPacage += mac;
        }
        byte[] MPBinary = hexStr2BinArr(MagicPacage);
        try {
            InetAddress address = InetAddress.getByName(ip);
            DatagramSocket socket = new DatagramSocket(port);
            DatagramPacket packet = new DatagramPacket(MPBinary, MPBinary.length, address, port);
            //发送udp数据包到广播地址
            socket.send(packet);
            socket.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    private static byte[] hexStr2BinArr(String hexString) {
        String hexStr = "0123456789ABCDEF";
        int len = hexString.length() / 2;
        byte[] bytes = new byte[len];
        byte high = 0;
        byte low = 0;
        for (int i = 0; i  
 

注意:当跨网段进行唤醒时,即发起唤醒的地址和被唤醒的目的地址不在同一个网段,是否需要做一些调整取决于你的网络配置。我这边的情况是,比如当50网段的服务器发送网络唤醒魔术包到62网段,是行不通的,需要在62网关下增加ip转发广播ip forward-broadcast。


以上所述就是小编给大家介绍的《每日一博 | java 通过网络唤醒实现远程开机》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 我们 的支持!


推荐阅读
  • 检查在所有可能的“?”替换中,给定的二进制字符串中是否出现子字符串“10”带 1 或 0 ... [详细]
  • 本文总结了JavaScript的核心知识点和实用技巧,涵盖了变量声明、DOM操作、事件处理等重要方面。例如,通过`event.srcElement`获取触发事件的元素,并使用`alert`显示其HTML结构;利用`innerText`和`innerHTML`属性分别设置和获取文本内容及HTML内容。此外,还介绍了如何在表单中动态生成和操作``元素,以便更好地处理用户输入。这些技巧对于提升前端开发效率和代码质量具有重要意义。 ... [详细]
  • JUC(三):深入解析AQS
    本文详细介绍了Java并发工具包中的核心类AQS(AbstractQueuedSynchronizer),包括其基本概念、数据结构、源码分析及核心方法的实现。 ... [详细]
  • vue引入echarts地图的四种方式
    一、vue中引入echart1、安装echarts:npminstallecharts--save2、在main.js文件中引入echarts实例:  Vue.prototype.$echartsecharts3、在需要用到echart图形的vue文件中引入:   importechartsfrom&amp;quot;echarts&amp;quot;;4、如果用到map(地图),还 ... [详细]
  • 在多线程并发环境中,普通变量的操作往往是线程不安全的。本文通过一个简单的例子,展示了如何使用 AtomicInteger 类及其核心的 CAS 无锁算法来保证线程安全。 ... [详细]
  • 2022年7月20日:关键数据与市场动态分析
    2022年7月20日,本文对当日的关键数据和市场动态进行了深入分析。主要内容包括:1. 关键数据的解读与趋势分析;2. 市场动态的变化及其对投资策略的影响;3. 相关经济指标的评估。通过这些分析,帮助读者更好地理解当前市场环境,为决策提供参考。 ... [详细]
  • 本文探讨了使用JavaScript在不同页面间传递参数的技术方法。具体而言,从a.html页面跳转至b.html时,如何携带参数并使b.html替代当前页面显示,而非新开窗口。文中详细介绍了实现这一功能的代码及注释,帮助开发者更好地理解和应用该技术。 ... [详细]
  • 在Android应用开发中,实现与MySQL数据库的连接是一项重要的技术任务。本文详细介绍了Android连接MySQL数据库的操作流程和技术要点。首先,Android平台提供了SQLiteOpenHelper类作为数据库辅助工具,用于创建或打开数据库。开发者可以通过继承并扩展该类,实现对数据库的初始化和版本管理。此外,文章还探讨了使用第三方库如Retrofit或Volley进行网络请求,以及如何通过JSON格式交换数据,确保与MySQL服务器的高效通信。 ... [详细]
  • 本文介绍了如何在iOS平台上使用GLSL着色器将YV12格式的视频帧数据转换为RGB格式,并展示了转换后的图像效果。通过详细的技术实现步骤和代码示例,读者可以轻松掌握这一过程,适用于需要进行视频处理的应用开发。 ... [详细]
  • 本文介绍了如何将包含复杂对象的字典保存到文件,并从文件中读取这些字典。 ... [详细]
  • C#实现文件的压缩与解压
    2019独角兽企业重金招聘Python工程师标准一、准备工作1、下载ICSharpCode.SharpZipLib.dll文件2、项目中引用这个dll二、文件压缩与解压共用类 ... [详细]
  • 本文介绍了Spring 2.0引入的TaskExecutor接口及其多种实现,包括同步和异步执行任务的方式。文章详细解释了如何在Spring应用中配置和使用这些线程池实现,以提高应用的性能和可管理性。 ... [详细]
  • 本文节选自《NLTK基础教程——用NLTK和Python库构建机器学习应用》一书的第1章第1.2节,作者Nitin Hardeniya。本文将带领读者快速了解Python的基础知识,为后续的机器学习应用打下坚实的基础。 ... [详细]
  • 题目描述:牛客网新员工Fish每天早上都会拿着一本英文杂志,在本子上写下一些句子。他的同事Cat对这些句子非常感兴趣,但发现这些句子的单词顺序被反转了。例如,“student. a am I”实际上是“I am a student.”。Cat请求你帮助他恢复这些句子的正常顺序。 ... [详细]
  • 本指南从零开始介绍Scala编程语言的基础知识,重点讲解了Scala解释器REPL(读取-求值-打印-循环)的使用方法。REPL是Scala开发中的重要工具,能够帮助初学者快速理解和实践Scala的基本语法和特性。通过详细的示例和练习,读者将能够熟练掌握Scala的基础概念和编程技巧。 ... [详细]
author-avatar
love生化丨丨丨爱跑酷
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有